// src/features/messages/components/thread.tsx
import React, {useEffect, useRef, useState} from 'react';
import {Button} from "@/components/ui/button";
import {AlertTriangle, Loader, XIcon} from "lucide-react";
import {useGetMessage} from "@/features/messages/api/use-get-message";
import Message from "@/components/social/message";
import {Member, Message as MessageType} from '@/lib/social/types'
import {useCurrentMember} from "@/features/workspaces/api/use-current-member";
import {useWorkspaceId} from "@/hooks/social/use-workspace-id";
import dynamic from "next/dynamic";
import Quill from "quill";
import {useCreateMessage} from "@/features/messages/api/use-create-message";
import {toast} from "sonner";
import {useChannelId} from "@/hooks/social/use-channel-id";
import {useGetMessages} from "@/features/messages/api/use-get-messages";
import {differenceInMinutes, format, isToday, isYesterday} from "date-fns";
import {formatDateLabel} from "@/lib/utils";
import {useCurrentUser} from "@/hooks/use-current-user";

// import {db} from '@/lib/db' db.message.fields.id.typeName
const Editor = dynamic(
    () => import("@/components/social/editor"),
    {ssr: false}
);

interface Props {
    messageId: string
    onClose: () => void
}

type CreateMessageValues = {
    channelId: string
    workspaceId: string
    userId: string
    body: string
    image: string
    parentMessageId: string
}

const TIME_THRESHOLD = 5

const Thread = ({messageId, onClose}: Props) => {
    const user = useCurrentUser()

    const workspaceId = useWorkspaceId()
    const channelId = useChannelId()

    const editorRef = useRef<Quill | null>(null)

    const [editorKey, setEditorKey] = useState(0)
    const [isPending, setIsPending] = useState(false)

    const [message, setMessage] = useState<MessageType>();
    const [loadingMessage, setLoadingMessage] = useState(false);
    const [curMember, setCurMember] = useState<Member>();
    const [editingId, setEditingId] = useState<string | null>(null);

    const {mutate: createMessage} = useCreateMessage();

    useEffect(() => {
        (async () => {
            const {
                isLoading, data
            } = await useGetMessage({id: messageId})
            setLoadingMessage(isLoading)
            setMessage(data)

            const {data: memData, isLoading: memLoading} = await useCurrentMember({
                workspaceId, userId: user?.id!
            })
            setLoadingMessage((prev) => prev || memLoading)
            setCurMember(memData)
        })()
    }, []);

    const [page, setPage] = useState(2)
    const [messages, setMessages] = useState<MessageType[]>();
    const [status, setStatus] = useState('');
    const loadMoreRef = useRef<Function>(null)
    // const canLoadMore = status === 'canLoadMore'
    const [canLoadMore, setCanLoadMore] = useState(status === 'canLoadMore');
    const isLoadingMore = status === 'loadingMore'
    useEffect(() => {
        (async () => {
            const {data, status: s, loadMode} = await useGetMessages({
                channelId,
                parentMessageId: messageId
            })
            // setMessages(data.data)
            setMessages(data)
            setStatus(s)
            // @ts-ignore
            loadMoreRef.current = loadMode
        })()
    }, [])

    const [groupedMessages, setGroupedMessages] = useState();
    useEffect(() => {
        // 根据哪一天进行分组
        // const groupedMessages = data?.reduce(
        const g = messages?.reduce(
            (groups, message) => {
                const date = new Date(message.createdAt!)
                const dateKey = format(date, 'yyyy-MM-dd')
                if (!groups[dateKey]) {
                    groups[dateKey] = []
                }
                // unshift 从尾部添加
                groups[dateKey].unshift(message)
                return groups
            },
            // ['2024-01-01', {1,2,3,4,...}]
            {} as Record<string, typeof messages>
        )
        // @ts-ignore
        setGroupedMessages(g)
    }, [messages])

    const handleSubmit = async ({
                                    body, image
                                }: {
        body: string,
        // image: File | null
        image: string | null
    }) => {
        try {
            setIsPending(true)
            editorRef?.current?.enable(false)

            const values: CreateMessageValues = {
                channelId, workspaceId, body,
                // image: image as string
                // @ts-ignore
                image: undefined,
                userId: user?.id!,
                parentMessageId: messageId
            }

            // 我在editor里的image input中直接转为base64了, 这里不需要创建url
            // if (image) {
            //     const url = await generateUploadUrl({image}, {
            //         throwError: true,
            //     })
            //     if(!url) throw new Error(`Url not found: ${url}`)
            // }

            await createMessage(values, {throwError: true})

            setEditorKey((prevKey) => prevKey + 1)
            // editorRef?.current?.setContents([])}
        } catch (e) {
            toast.error('Failed to send message')
        } finally {
            setIsPending(false)
            editorRef?.current?.enable(true)
        }
    }

    if (loadingMessage || status === 'loadingFirstPage') return <div
        className={`flex h-full items-center justify-center`}>
        <Loader className={`size-5 animate-spin text-muted-foreground`}/>
    </div>

    if (!message)
        return <div className={`h-full flex flex-col`}>
            <div className={`h-[49px] flex justify-between items-center px-4 border-b`}>
                <p className={`text-lg font-bold`}>Thread</p>
                <Button onClick={onClose} size={'iconSm'} variant={'ghost'}>
                    <XIcon className={`size-5 stroke-[1.5]`}/>
                </Button>
            </div>
            <div className={`flex flex-col gap-y-2 h-full items-center justify-center`}>
                <AlertTriangle className={`size-5 text-muted-foreground`}/>
                <p className={`text-sm text-muted-foreground`}>Message not found</p>
            </div>
        </div>

    return (
        <div className={`h-full flex flex-col`}>
            <div className={`h-[49px] flex justify-between items-center px-4 border-b`}>
                <p className={`text-lg font-bold`}>Thread</p>
                <Button onClick={onClose} size={'iconSm'} variant={'ghost'}>
                    <XIcon className={`size-5 stroke-[1.5]`}/>
                </Button>
            </div>
            <div className={`flex flex-1 flex-col-reverse flex-col1 pb-4 overflow-y-auto messages-scrollbar`}>
                <div className={`w-full h-16 flex items-center justify-center`}>
                    <Button
                        size={'sm'}
                        variant={'outline'}
                        className={``}
                        onClick={() => {
                            let loadMore = loadMoreRef.current!
                            // @ts-ignore
                            loadMore(page).then((data) => {
                                // @ts-ignore
                                if (page <= data.pages) {
                                    setMessages([
                                        // @ts-ignore
                                        ...defaultData,
                                        // @ts-ignore
                                        // ...data.data
                                        ...data
                                    ])
                                    setPage((prev) => prev + 1)
                                } else {
                                    setCanLoadMore(false)
                                }
                            })
                        }}
                        disabled={!canLoadMore}
                    >
                        {canLoadMore ? 'Load More' : 'No More'}
                    </Button>
                </div>
                {Object.entries(groupedMessages || {}).map(([dateKey, messages]) => (
                    <div key={dateKey}>
                        <div className={`text-center my-2 relative`}>
                            <hr className={`absolute top-1/2 left-0 right-0 border-t border-gray-300`}/>
                            <span className={`relative inline-block bg-white px-4 py-1 rounded-full text-xs
                        border border-gray-300 shadow-sm`}>
                            {formatDateLabel(dateKey)}
                        </span>
                        </div>
                        {/*@ts-ignore*/}
                        {messages.map((message, index) => {
                                // @ts-ignore
                                const prevMessage = messages[index - 1]
                                const isCompact =
                                    /*
                                    prevMessage && prevMessage.user?.id === message.user?.id
                                    && differenceInMinutes( // 相差不超过5分钟
                                    new Date(message.createdAt),
                                    new Date(prevMessage.createdAt),
                                    ) < TIME_THRESHOLD
                                    */
                                    prevMessage && prevMessage.member.user?.id === message.member.user?.id
                                    && differenceInMinutes( // 相差不超过5分钟
                                        new Date(message.createdAt!),
                                        new Date(prevMessage.createdAt!),
                                    ) < TIME_THRESHOLD


                                return <Message
                                    key={message.id}
                                    id={message.id}
                                    memberId={message.memberId}
                                    // memberId={'malred'}
                                    authorImage={message.member.user.image}
                                    authorName={message.member.user.name}
                                    // authorImage={'https://picsum.photos/200'}
                                    // authorName={'malred'}
                                    isAuthor={message.memberId === curMember?.id}
                                    reactions={message.relation!}
                                    body={message.body}
                                    image={message.image}
                                    updatedAt={message.updatedAt!}
                                    createdAt={message.createdAt!}
                                    isEditing={editingId === message.id}
                                    setEditingId={setEditingId}
                                    isCompact={isCompact}
                                    hideThreadButton
                                    threadCount={message.threadCount}
                                    threadImage={message.threadImage}
                                    threadTimestamp={parseInt(message.threadTimestamp)}
                                />
                            }
                        )}
                    </div>
                ))}
                <Message
                    hideThreadButton
                    memberId={message.memberId}
                    // memberId={'malred'}
                    // @ts-ignore
                    authorImage={message.member.user.image}
                    // authorImage={`/logo.png`}
                    // @ts-ignore
                    authorName={message.member.user.name }
                    isAuthor={message.memberId === curMember?.id}
                    body={message.body}
                    image={message.image}
                    createdAt={message.createdAt!}
                    updatedAt={message.updatedAt!}
                    id={message.id}
                    // @ts-ignore
                    reactions={message.relation}
                    isEditing={editingId === message.id}
                    setEditingId={setEditingId}
                />
                {isLoadingMore && (
                    <div className={`text-center my-2 relative`}>
                        <hr className={`absolute top-1/2 left-0 right-0 border-t border-gray-300`}/>
                        <span className={`relative inline-block bg-white px-4 py-1 rounded-full text-xs
                        border border-gray-300 shadow-sm`}>
                           <Loader className={`size-4 animate-spin`}/>
                        </span>
                    </div>
                )}
            </div>
            <div className={`px-4`}>
                <Editor
                    key={editorKey}
                    // @ts-ignore
                    onSubmit={handleSubmit}
                    innerRef={editorRef}
                    disabled={isPending}
                    placeholder={`Reply...`}
                />
            </div>
        </div>
    );
};

export default Thread;